<template>
  <div>
    <el-container>
      <el-header>
        <el-menu
          :default-active="activeIndex"
          class="el-menu-demo"
          mode="horizontal"
          @select="handleSelect"
        >
          <el-menu-item index="1" ref=""> 上传扫描图片 </el-menu-item>
          <el-menu-item index="2"> 模型交互 </el-menu-item>
          <!-- <el-menu-item index="3"> 点云编辑 </el-menu-item> -->
        </el-menu>
      </el-header>
      <el-container>
        <el-aside width="200px">
          <el-menu>
            <div
              v-for="(models_groupname, groupindex) in groups"
              :key="groupindex"
            >
              <el-submenu :index="groupindex">
                <template slot="title"
                  ><i class="el-icon-folder"></i
                  >{{ models_groupname[1] }}</template
                >
                <el-menu-item-group>
                  <el-menu-item
                    v-for="(item, modelindex) in models_groupname[0]"
                    :key="modelindex"
                    @click="handleModelSelect(models_groupname[1], item)"
                  >
                    {{ item }}
                  </el-menu-item>
                </el-menu-item-group>
              </el-submenu>
            </div>
          </el-menu>
        </el-aside>
        <el-main>
          <div>
            <div id="pointcloud"></div>
            <div class="seg_div">
              <el-image
                style="width: 480px; height: 640px"
                :src="render_src"
                :fit="fill"
                alt="暂无图片"
              ></el-image>
            </div>
          </div>
        </el-main>
      </el-container>
      <el-footer style="padding-left: 200px">
        <div style="background-color: aquamarine">
          <div class="seg_div">
            <el-button type="primary" round @click="handleSubmitPos(pos)"
              >提交渲染视角</el-button
            >
          </div>

          <div class="seg_div">
            <el-button type="primary" round @click="handleDownloadPicture()"
              >下载图片</el-button
            >
          </div>
        </div>
      </el-footer>
    </el-container>
  </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// import { FirstPersonControls } from "three/addons/controls/FirstPersonControls.js";
// import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
import FileSaver from "file-saver";
import axios from "axios";
export default {
  data() {
    return {
      activeIndex: "2",
      groups: [
        [["模型1", "模型2", "模型3"], "模型分组一"],
        [["模型4", "模型5", "模型6"], "模型分组二"],
      ],
      camera: new THREE.PerspectiveCamera(30, 1, 1, 3000),
      modelName: "",
      render_src:
        "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
    };
  },
  methods: {
    handleSelect(key, keyPath) {
      console.log(key, keyPath);
      let index2path = ["/upload", "/render", "/pointcloudedit"];
      if (index2path[key - 1] != "/render")
        this.$router.push({
          path: index2path[key - 1],
        });
    },
    handleModelSelect(groupName, modelName) {
      alert("当前选中" + groupName + "," + modelName);
      this.modelName = groupName + modelName;

      axios
        .post("http://192.168.1.103:8080/getModel", {
          groupName: groupName,
          modelName: modelName,
        })
        .then((result) => {
          // console.log(result.data.data);
          this.renderPointCloud(result.data.data);
        })
        .catch(() => {
          alert("加载模型失败");
        });
    },
    handleSubmitPos(pos) {
      console.log(pos);
      let vec = new THREE.Vector3();
      this.camera.getWorldDirection(vec);
      let front = { x: -vec.x, y: -vec.y, z: -vec.z };
      let tran = {
        x: this.camera.position.x,
        y: this.camera.position.y,
        z: this.camera.position.z,
      };
      console.log(this.modelName);
      axios
        .post("http://192.168.1.103:8080/renderPose", {
          front: front,
          tran: tran,
          modelName: this.modelName,
        })
        .then((result) => {
          console.log(result.data.msg);
          // this.renderPointCloud(result.data.data);
          this.render_src = result.data.data;
        })
        .catch(() => {
          alert("上传视角失败");
        });
    },
    handleDownloadPicture() {
      let url = this.render_src;
      return new Promise((resolve, reject) => {
        const image = new Image();
        image.crossOrigin = "Anonymous";
        image.src = url;

        image.onload = () => {
          const canvas = document.createElement("canvas");
          canvas.width = image.width;
          canvas.height = image.height;

          canvas.getContext("2d").drawImage(image, 0, 0);

          canvas.toBlob((blob) => {
            FileSaver.saveAs(blob, "downloaded.png");
            resolve();
          }, "image/png");
        };

        image.onerror = (err) => {
          reject(err);
        };
      });
    },
    renderPointCloud(filePath) {
      //rendering the pointcloud
      // 三维场景
      const scene = new THREE.Scene();
      // 模型对象
      // const geometry = new THREE.BoxGeometry(50, 50, 50);
      // const material = new THREE.MeshBasicMaterial({
      //   color: 0x0000ff,
      // });
      // const mesh = new THREE.Mesh(geometry, material);
      // scene.add(mesh);
      // 加载并展示PLY点云文件
      const loader = new PLYLoader();
      loader.load(filePath, function (geometry) {
        // 提取颜色属性
        const colors = geometry.attributes.color;
        // 将顶点颜色应用到几何体
        geometry.setAttribute("color", colors);
        // 创建材质
        const material = new THREE.PointsMaterial({
          //  colors:0xff0000,
          size: 0.3 ,
          vertexColors: true,
        });

        // 创建网格对象
        const mesh = new THREE.Points(geometry, material);
        scene.add(mesh);
      });
      // AxesHelper：辅助观察的坐标系
      const axesHelper = new THREE.AxesHelper(2);
      scene.add(axesHelper);
      const width = 480; //宽度
      const height = 640; //高度
      // 相机

      this.camera = new THREE.PerspectiveCamera(60, width / height, 1, 3000);
      var camera = this.camera;
      camera.position.set(-4.68, 0.31, -2.25);
      // camera.position.set(0, 0, 0);
      let lookAtPoint = new THREE.Vector3(
        -4.68 + 0.02 * 10,
        0.31 - 0.15 * 10,
        -2.25 + 0.98 * 10
      );
      camera.lookAt(lookAtPoint);

      // WebGL渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height);
      renderer.render(scene, camera);
      //three.js执行渲染命令会输出一个canvas画布(HTML元素)，你可以插入到web页面中
      let parentDiv = document.getElementById("pointcloud");
      parentDiv.innerHTML = "";
      parentDiv.appendChild(renderer.domElement);

      // 设置相机控件轨道控制器OrbitControls
      let controls = new OrbitControls(
        camera,
        renderer.domElement,
        lookAtPoint
      );
      // controls.target=lookAtPoint;

      // var controls = new FirstPersonControls(camera, renderer.domElement);
      // var clock = new THREE.Clock();
      document.addEventListener("keydown", onKeyDown, false);

      // 键盘按下事件处理函数
      function onKeyDown(event) {
        // 获取按下的键码
        var keyCode = event.keyCode;

        // 根据键码执行相应的操作
        if (keyCode === 65) {
          // 按下了A键
          console.log("A键按下");
          lookAtPoint.x -= 0.1;
          camera.position.x -= 0.1;
        } else if (keyCode === 83) {
          // 按下了S键
          console.log("S键按下");
          lookAtPoint.z -= 0.1;
          camera.position.z -= 0.1;
        } else if (keyCode === 87) {
          // 按下了W键
          console.log("W键按下");
          lookAtPoint.z += 0.1;
          camera.position.z += 0.1;
        } else if (keyCode === 68) {
          // 按下了D键
          console.log("D键按下");
          lookAtPoint.x += 0.1;
          camera.position.x += 0.1;
        } else if (keyCode === 82) {
          // 按下了R键
          console.log("R键按下");
          lookAtPoint.y -= 0.1;
          camera.position.y -= 0.1;
        } else if (keyCode === 70) {
          // 按下了F键
          console.log("F键按下");
          lookAtPoint.y += 0.1;
          camera.position.y += 0.1;
        }
      }
      function render() {
        // controls.update(clock.getDelta());
        controls.target = lookAtPoint;
        controls.update();
        camera.rotation.z += Math.PI; //纠正
        // let vec=camera.target-camera.position;
        // this.pose.front={x:-vec.y,y:-vec.x,z:-vec.z};
        // this.pose.pos={x:camera.position.x,y:camera.position.y,z:camera.position.z};
        renderer.setClearColor(0x444444);
        renderer.render(scene, camera);
        requestAnimationFrame(render);
      }
      render();
    },
  },
  mounted() {
    //set event
    // this.renderPointCloud("http://192.168.1.114:8080/分组1模型20.ply");
    this.renderPointCloud("out.ply");
    // renderer.render(scene, camera); 
    //******
    //show available model
    axios
      .get("http://192.168.1.103:8080/availableModel")
      .then((result) => {
        console.log(result.data.data);
        let data = [];
        result.data.data.forEach((group) => {
          let modelList = [];
          group.modelNames.forEach((modelNames) => {
            modelList.push(modelNames);
          });
          data.push([modelList, group.groupName]);
        });
        this.groups = data;
      })
      .catch(() => {
        alert("获取可用模型失败，请联系管理员");
      });
  },
};
</script>
<style>
#pointcloud {
  display: flex;
  justify-content: center;
  align-items: center;
  float: left;
  /* background-color: rgb(240, 255, 127);  */
  width: 50%;
  height: 100%;
}

.seg_div {
  float: left;
  /* background-color: rgb(240, 255, 127);  */
  width: 50%;
  height: 100%;
}
canvas {
  touch-action: none;
}
</style>